package com.jsyso.jadmin.sys.service;

import java.util.List;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.jsyso.jadmin.common.config.Global;
import com.jsyso.jadmin.common.security.Password;
import com.jsyso.jadmin.common.service.BaseService;
import com.jsyso.jadmin.sys.utils.UserUtils;
import com.jsyso.jsyso.cache.Cache;
import com.jsyso.jsyso.cache.Element;
import com.jsyso.jsyso.db.Dao;
import com.jsyso.jsyso.util.JsMap;

/**
 * 用户service
 * @author janjan, xujian_jason@163.com
 *
 */
@Service
public class UserService extends BaseService {
	public static final String DEFAULT_MESSAGE_PARAM 	= "message";
	// key：以id缓存user
	public static final String CACHE_KEY_ID 			= "user.id@";
	// key：以loginName缓存user
	public static final String CACHE_KEY_LOGINNAME 		= "user.loginName@";
	
	private Dao roleDao = Dao.get("sys_role sr");
	private Dao menuDao = Dao.get("sys_menu sm");
	private Dao userRoleDao = Dao.get("sys_user_role", "role_id", "user_id");
	@Autowired
	private Cache cache;
	
	@Override
	protected Dao dao() {
		return Dao.get("sys_user su");
	}
	
	public List<JsMap> getRoleList(Long userId, String loginName) {
		JsMap params = JsMap.create("del_flag", Global.NO);
		params.set("", new String[]{
				"exp",
				"EXISTS (SELECT role_id FROM sys_user_role sur WHERE sr.id = sur.role_id AND user_id = "+userId+")"
		});
		return roleDao.select(params);
	}
	
	public List<JsMap> getMenuList(Long userId, String loginName) {
		JsMap params = JsMap.create("del_flag", Global.NO);
		if(!UserUtils.isSysAdmin(userId)) {
			params.set("", new String[]{
					"exp",
					"EXISTS (SELECT menu_id FROM sys_role_menu srm WHERE EXISTS (SELECT role_id FROM sys_user_role sur WHERE srm.role_id = sur.role_id AND user_id = "+userId+")"
							+ " AND sm.id = srm.menu_id)"
			});
		}
		return menuDao.order("sm.sort ASC, sm.id DESC").select(params);
	}

	public void clearCache(JsMap user) {
		if(user == null) 
			return ;
		if(user.containsKey("id")) 
			cache.remove(Element.create(CACHE_KEY_ID + user.get("id", 0l, Long.class)));
		if(user.containsKey("loginName")) 
			cache.remove(Element.create(CACHE_KEY_LOGINNAME + user.get("loginName", "", String.class)));
	}

	@Override
	public JsMap get(Long id) {
		if(id == null || id <= 0) 
			return null;
		String cacheKey = CACHE_KEY_ID + id;
		JsMap user = cache.get(Element.create(cacheKey));
		if(user == null && (user = super.get(id)) != null) {
			String cacheNameKey = CACHE_KEY_LOGINNAME + user.get("loginName", String.class);
			cache.put(Element.create(cacheKey, user).setCacheName(USER_CACHE));
			cache.put(Element.create(cacheNameKey, user).setCacheName(USER_CACHE));
		}
		return user;
	}
	
	public JsMap getByLoginName(String loginName) {
		if(StringUtils.isBlank(loginName)) 
			return null;
		String cacheNameKey = CACHE_KEY_LOGINNAME + loginName;
		JsMap user = cache.get(Element.create(cacheNameKey));
		if(user == null && 
				(user = dao().find(JsMap.create("login_name", loginName))) != null) {
			String cacheKey = CACHE_KEY_ID + user.get("id", 0l, Long.class);
			cache.put(Element.create(cacheKey, user).setCacheName(USER_CACHE));
			cache.put(Element.create(cacheNameKey, user).setCacheName(USER_CACHE));
		}
		return user;
	}
	
	public int updatePasswordById(Long id, String loginName, String password) {
		int result = dao().update(JsMap.create("id", id).set("password", Password.entryptPassword(password)));
		if(result > 0) 
			clearCache(JsMap.create("id", id).set("loginName", loginName));
		return result;
	}
	
	public List<JsMap> userRoleByUserId(Long userId) {
		return userRoleDao.select(JsMap.create("user_id", userId));
	}
	
	public int deleteUserRoleByUserId(Long userId) {
		return userRoleDao.delete(JsMap.create("user_id", userId));
	}
	
	public int addUserRoles(List<JsMap> userRoles) {
		return userRoleDao.insertAll(userRoles);
	}
	
	public int saveUserRoles(Long userId, List<JsMap> userRoles) {
		deleteUserRoleByUserId(userId);
		return addUserRoles(userRoles);
	}
	
	public List<JsMap> listByRoleEname(String roleEname) {
		JsMap role = roleDao.find(JsMap.create("enname", roleEname));
		Long roleId = role.get("id", 0l, Long.class);
		List<JsMap> list = dao().select(JsMap.create("del_flag", Global.NO).set("", new String[]{
			"exp", "EXISTS (SELECT user_id FROM sys_user_role sur WHERE role_id = "+roleId+" AND su.id = sur.user_id)"	
		}));
		return list;
	}
	
}
